home *** CD-ROM | disk | FTP | other *** search
/ Workbench Add-On / Workbench Add-On - Volume 1.iso / BBS-Archive / Comm / AmiTCP30b2.lha / src / amitcp / kern / amiga_rexx.c < prev    next >
C/C++ Source or Header  |  1994-01-05  |  8KB  |  277 lines

  1. RCS_ID_C="$Id: amiga_rexx.c,v 1.17 1994/01/05 10:23:02 jraja Exp $";
  2. /*
  3.  * Copyright (c) 1993 AmiTCP/IP Group, <amitcp-group@hut.fi>
  4.  *                    Helsinki University of Technology, Finland.
  5.  *                    All rights reserved.
  6.  *
  7.  * $Log: amiga_rexx.c,v $
  8.  * Revision 1.17  1994/01/05  10:23:02  jraja
  9.  * Added new functions: rexx_show() and rexx_hide().
  10.  * Removed AddPort() and RemPort() calls from other functions.
  11.  *
  12.  * Revision 1.16  1993/07/26  08:22:50  jraja
  13.  * Changed ARexx port name from 'NETTRACE' to 'AMITCP'.
  14.  *
  15.  * Revision 1.15  1993/06/04  11:16:15  jraja
  16.  * Fixes for first public release.
  17.  *
  18.  * Revision 1.14  1993/05/17  01:07:47  ppessi
  19.  * Changed RCS version.
  20.  *
  21.  * Revision 1.13  1993/04/25  03:04:51  jraja
  22.  * Moved RemPort() upper in function rexx_deinit(). Changed bsd_free() type
  23.  * argument to the same as the corresponding bsd_malloc().
  24.  *
  25.  * Revision 1.12  93/04/23  21:03:08  21:03:08  puhuri (Markus Peuhkuri)
  26.  * Add code to check if we had to alloc more buffer and free it.
  27.  * 
  28.  * Revision 1.11  93/04/23  00:28:34  00:28:34  ppessi (Pekka Pessi)
  29.  * using now parseline() (in amiga_config.c) to parse Arexx messages
  30.  * 
  31.  * Revision 1.10  93/04/21  19:08:04  19:08:04  puhuri (Markus Peuhkuri)
  32.  * Add new feature: Connections. UNFINISHED.
  33.  *
  34.  * Revision 1.9  93/04/06  15:15:39  15:15:39  jraja (Jarno Tapio Rajahalme)
  35.  * Changed spl function return value storage to spl_t,
  36.  * changed bcopys and bzeros to aligned and/or const when possible,
  37.  * added inclusion of conf.h to every .c file.
  38.  * 
  39.  * Revision 1.8  93/03/20  07:06:21  07:06:21  ppessi (Pekka Pessi)
  40.  * Support multiple instances. Library name, rexx port name and task name fixed.
  41.  * 
  42.  * Revision 1.7  93/03/05  21:11:07  21:11:07  jraja (Jarno Tapio Rajahalme)
  43.  * Fixed includes (again).
  44.  * 
  45.  * Revision 1.6  93/03/05  12:28:33  12:28:33  jraja (Jarno Tapio Rajahalme)
  46.  * Changed RexxSysBase and UtilityBase to struct Library in GCC to 
  47.  * follow SASC convention.
  48.  * Removed __stdargs in GCC.
  49.  * 
  50.  * Revision 1.5  93/03/05  03:25:59  03:25:59  ppessi (Pekka Pessi)
  51.  * Compiles with SASC. Initial test version.
  52.  * 
  53.  * Revision 1.4  93/03/04  10:59:50  10:59:50  jraja (Jarno Tapio Rajahalme)
  54.  * Minor cosmetic changes.
  55.  * 
  56.  * Revision 1.3  93/03/02  18:23:12  18:23:12  puhuri (Markus Peuhkuri)
  57.  * Transformed toupper to utility/ToUpper and add open&close for utility.lib
  58.  * 
  59.  * Revision 1.2  93/03/01  19:11:56  19:11:56  puhuri (Markus Peuhkuri)
  60.  * Major rewrite to remove simplerexx.c and to make arexx-interface
  61.  * more efficient.
  62.  * 
  63.  * Revision 1.1  93/02/25  19:59:18  19:59:18  puhuri (Markus Peuhkuri)
  64.  * Initial revision
  65.  * 
  66.  */
  67.  
  68. #include <conf.h>
  69. #include <sys/param.h>
  70. #include <sys/systm.h>
  71. #include <sys/malloc.h>
  72.  
  73. #include <kern/amiga_config.h>
  74. #include <kern/amiga_includes.h>
  75. #include <dos/rdargs.h>
  76.  
  77. #if __GNUC__
  78. char *strtok(char *,char *);
  79. #endif
  80.  
  81. #include <rexx/storage.h>
  82. #include <rexx/rxslib.h>
  83.  
  84. #if __SASC
  85. #include <proto/rexxsyslib.h>
  86. #include <proto/utility.h>
  87. #elif __GNUC__
  88. /*
  89.  * predefine RexxSysBase and UtilityBase to Library to follow SASC convention.
  90.  */
  91. #define BASE_EXT_DECL extern struct Library * RexxSysBase;
  92. #define BASE_NAME (struct RexxSysBase *)RexxSysBase
  93. #include <inline/rexxsyslib.h>
  94. struct ClockData;
  95. #define BASE_EXT_DECL extern struct Library * UtilityBase;
  96. #define BASE_NAME (struct UtilityBase *)UtilityBase
  97. #include <inline/utility.h>
  98. #endif
  99.  
  100. /*
  101.  * The rexx port and error name may change, if there is already an 
  102.  * AmiTCP/IP task running
  103.  */ 
  104. #define D_REXX_PORT_NAME     "AMITCP"
  105. #define REXX_ERROR_POSTFIX  ".LASTERROR"
  106. #define D_REXX_ERROR_NAME     D_REXX_PORT_NAME REXX_ERROR_POSTFIX
  107.  
  108. UBYTE   T_REXX_PORT_NAME[]  = D_REXX_PORT_NAME;
  109. UBYTE  *REXX_PORT_NAME      = T_REXX_PORT_NAME;
  110.  
  111. UBYTE   T_REXX_ERROR_NAME[] = D_REXX_ERROR_NAME;
  112. UBYTE  *REXX_ERROR_NAME     = T_REXX_ERROR_NAME;
  113.  
  114. #define    REXX_RETURN_ERROR   ((struct RexxMsg *)-1L)
  115.  
  116. extern LONG nthLibrary;
  117.  
  118. #include <kern/amiga_rexx.h>
  119.  
  120. /*
  121.  * This function returns a structure that contains the commands sent from
  122.  * ARexx...  You will need to parse it and return the structure back
  123.  * so that the memory can be freed...
  124.  *
  125.  * This returns NULL if there was no message...
  126.  */
  127. STKARGFUN long SetRexxVar(struct Message *, char *, char *, long);
  128.  
  129. struct Library *UtilityBase = NULL;
  130. struct Library *RexxSysBase = NULL;
  131.  
  132. struct MsgPort *ARexxPort = NULL;
  133.  
  134. ULONG 
  135. rexx_init(void)
  136. {
  137.   if (
  138. #ifdef DEBUG
  139.       (REXX_PORT_NAME = 
  140.        bsd_malloc(sizeof(D_REXX_PORT_NAME) + 3, M_CFGVAR, M_WAITOK)) &&
  141.       (REXX_ERROR_NAME = 
  142.        bsd_malloc(sizeof(D_REXX_ERROR_NAME) + 3, M_CFGVAR, M_WAITOK)) &&
  143. #endif
  144.       (UtilityBase = OpenLibrary("utility.library", 37)) &&
  145.       (RexxSysBase = OpenLibrary("rexxsyslib.library", 0L))) {
  146.     ARexxPort = CreateMsgPort();
  147.     if (ARexxPort) {
  148. #ifdef DEBUG
  149.       strcpy(REXX_PORT_NAME, D_REXX_PORT_NAME);
  150.       strcpy(REXX_ERROR_NAME, D_REXX_PORT_NAME);
  151.       if (nthLibrary) {
  152.     REXX_PORT_NAME[sizeof(D_REXX_PORT_NAME)-1] = '.'; 
  153.     REXX_PORT_NAME[sizeof(D_REXX_PORT_NAME)] = '0' + nthLibrary;
  154.     REXX_PORT_NAME[sizeof(D_REXX_PORT_NAME)+1] = '\0';
  155.     REXX_ERROR_NAME[sizeof(D_REXX_PORT_NAME)-1] = '.'; 
  156.     REXX_ERROR_NAME[sizeof(D_REXX_PORT_NAME)] = '0' + nthLibrary;
  157.     REXX_ERROR_NAME[sizeof(D_REXX_PORT_NAME)+1] = '\0';
  158.       }
  159.       strcat(REXX_ERROR_NAME, REXX_ERROR_POSTFIX);
  160. #endif
  161.  
  162.       ARexxPort->mp_Node.ln_Name = REXX_PORT_NAME; 
  163.       return (ULONG)1 << ARexxPort->mp_SigBit;
  164.     }
  165.   }
  166.   rexx_deinit();
  167.   return (0);
  168. }
  169.  
  170. static BOOL rexx_shown = FALSE;
  171.  
  172. BOOL
  173. rexx_show(void)
  174. {
  175.   if (!rexx_shown && ARexxPort) {
  176.     AddPort(ARexxPort);    /* No return value! */
  177.     rexx_shown = TRUE;
  178.     return TRUE;
  179.   }
  180.   return FALSE;
  181. }
  182.  
  183. BOOL
  184. rexx_hide(void)
  185. {
  186.   if (rexx_shown) {
  187.     if (ARexxPort) {
  188.       /*
  189.        * Remove the port from the system's message port list so that the
  190.        * port cannot be found any more
  191.        */
  192.       RemPort(ARexxPort);
  193.     }
  194.     rexx_shown = FALSE;
  195.   }
  196.   return TRUE;
  197. }
  198.  
  199. void rexx_deinit(void)
  200. {
  201.   struct RexxMsg *rmsg;
  202.   static STRPTR errstr = "99: Port Closed!";
  203.  
  204.   if (RexxSysBase) {
  205.     if (ARexxPort) {
  206.       rexx_hide();
  207.       /*
  208.        * Reply to all messages received with error code set.
  209.        */
  210.       while(rmsg = (struct RexxMsg *)GetMsg(ARexxPort)){
  211.     SetRexxVar((struct Message *)rmsg, REXX_ERROR_NAME, 
  212.            errstr, strlen(errstr));
  213.     if (rmsg != REXX_RETURN_ERROR){
  214.       rmsg->rm_Result2 = 0;
  215.       rmsg->rm_Result1 = 100;
  216.       ReplyMsg((struct Message *)rmsg);
  217.     }
  218.       }
  219.       DeleteMsgPort(ARexxPort);
  220.       ARexxPort = NULL;
  221.     }
  222.     CloseLibrary(RexxSysBase);
  223.     RexxSysBase = NULL;
  224.   }
  225.   if (UtilityBase) {
  226.     CloseLibrary(UtilityBase);
  227.     UtilityBase = NULL;
  228.   }
  229. }
  230.  
  231. BOOL rexx_poll(void)
  232. {
  233.   struct RexxMsg *rmsg;
  234.       
  235.   if ((rmsg = (struct RexxMsg *)GetMsg(ARexxPort))
  236.       && rmsg != REXX_RETURN_ERROR 
  237.       && IsRexxMsg(rmsg)) {
  238.     UBYTE rbuf[REPLYBUFLEN];
  239.     struct CSource result;
  240.     struct CSource csarg;
  241.     UBYTE *errstr = NULL;
  242.     LONG error = 0;
  243.  
  244.     result.CS_Buffer = rbuf; 
  245.     result.CS_Length = REPLYBUFLEN - 1;
  246.     result.CS_CurChr = 0;
  247.  
  248.     csarg.CS_Buffer = ARG0(rmsg);
  249.     csarg.CS_Length = LengthArgstring(ARG0(rmsg)) + 1;
  250.     csarg.CS_CurChr = 0;
  251.     csarg.CS_Buffer[csarg.CS_Length - 1] = '\n'; /* Sentinel */
  252.  
  253.     rmsg->rm_Result1 = rmsg->rm_Result2 = 0;
  254.  
  255.     if (error = parseline(&csarg, &errstr, &result)) {
  256.       SetRexxVar((struct Message*)rmsg, REXX_ERROR_NAME,
  257.          errstr, (long)strlen(errstr));
  258.       rmsg->rm_Result1 = error;
  259.     } else {
  260.       if (rmsg->rm_Action & (1L << RXFB_RESULT)) {
  261.     rmsg->rm_Result2 = (LONG)
  262.       CreateArgstring(result.CS_Buffer, (LONG)strlen(result.CS_Buffer));
  263.       }
  264.     }
  265.  
  266.     csarg.CS_Buffer[csarg.CS_Length - 1] = '\0';
  267.  
  268.     ReplyMsg((struct Message *)rmsg);
  269.  
  270.     if (result.CS_Buffer != rbuf) /* We've allocated memory */
  271.       bsd_free(result.CS_Buffer, M_TEMP); 
  272.  
  273.     return TRUE;
  274.   }
  275.   return FALSE;
  276. }
  277.